// MegaDrawerOrganize.cpp : implementation file
//

#include "stdafx.h"
#include "vc10.h"
#include "resource.h"
#include "MegaDrawerOrganize.h"
#include "../GUI/Messages.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMegaDrawerOrganize
#define IDC_CURRENT		2000
#define IDC_ID			2005
#define IDC_PASS		2006
#define IDC_IP			2007
#define IDC_PORT		2008
#define IDC_ADD			2009
#define IDC_DEL			2010
#define IDC_UPDATE		2011

#define STRING_PARAM	"%s %s %s %s"

CMegaDrawerOrganize::CMegaDrawerOrganize()
{
}

CMegaDrawerOrganize::~CMegaDrawerOrganize()
{
}

void CMegaDrawerOrganize::SetBitmaps(UINT uiSkinSingle, UINT uiSkinDouble, UINT uiSkinSingleUn, UINT uiSkinDoubleUn)
{
	CMegaDrawer::SetBitmaps(uiSkinSingle, uiSkinDouble, uiSkinSingleUn, uiSkinDoubleUn);

	CRect rc(5, 0, 15, 15);
	CRect rcCombo(10, 10, 150, 150);
	DWORD dwStyle = WS_CHILD|WS_TABSTOP|WS_VSCROLL|CBS_OWNERDRAWFIXED|CBS_HASSTRINGS|CBS_AUTOHSCROLL;
	m_cbCurrent.SetBitmap(IDB_ICON_WHITE);
	m_cbCurrent.Create	(dwStyle|CBS_DROPDOWNLIST, rcCombo, this, IDC_CURRENT);
	m_cbSite.Create		(dwStyle|CBS_DROPDOWN, rcCombo, this, IDC_SITE);
	m_cbBuilding.Create	(dwStyle|CBS_DROPDOWN, rcCombo, this, IDC_BUILDING);
	m_cbRoom.Create		(dwStyle|CBS_DROPDOWN, rcCombo, this, IDC_ROOM);
	m_cbCamera.Create	(dwStyle|CBS_DROPDOWN, rcCombo, this, IDC_CAMERA);

	dwStyle = WS_CHILD|WS_TABSTOP|ES_LEFT|ES_AUTOHSCROLL;
	m_ID.Create			(dwStyle|ES_NUMBER, rc, this, IDC_ID);
	m_Pass.Create		(dwStyle|ES_PASSWORD, rc, this, IDC_PASS);
	m_IP.Create			(dwStyle, rc, this, IDC_IP);
	m_Port.Create		(dwStyle|ES_NUMBER, rc, this, IDC_PORT);

	dwStyle = WS_CHILD|BS_PUSHBUTTON;
	m_btnAdd.Create		("", dwStyle, rc, this, IDC_ADD);
	m_btnDelete.Create	("", dwStyle, rc, this, IDC_DEL);
	m_btnUpdate.Create	("", dwStyle, rc, this, IDC_UPDATE);
	m_btnAdd.SetBitmaps		(IDB_ADD_OUT, IDB_ADD_DOWN, IDB_ADD_OVER);
	m_btnDelete.SetBitmaps	(IDB_DEL_OUT, IDB_DEL_DOWN, IDB_DEL_OVER);
	m_btnUpdate.SetBitmaps	(IDB_UPDATE_OUT, IDB_UPDATE_DOWN, IDB_UPDATE_OVER);
	m_btnAdd.SetBackgroundBmp(m_pSkinSingle);
	m_btnDelete.SetBackgroundBmp(m_pSkinSingle);
	m_btnUpdate.SetBackgroundBmp(m_pSkinSingle);
}

void CMegaDrawerOrganize::RepositionControls()
{
	if(m_bActive)
	{
		if(m_nSize == 1)
		{
			m_cbCurrent.SetWindowPos	(NULL,   3,  40, 320, 160, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_cbSite.SetWindowPos		(NULL,  80,  75, 90,  160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbBuilding.SetWindowPos	(NULL, 254,  75, 60,  160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbRoom.SetWindowPos		(NULL,  80, 100, 90,  160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbCamera.SetWindowPos		(NULL, 254, 100, 60,  160, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_ID.SetWindowPos		(NULL,  80, 136,  50,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_Pass.SetWindowPos		(NULL, 244, 136,  70,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_IP.SetWindowPos		(NULL,  80, 160, 110,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_Port.SetWindowPos		(NULL, 274, 160,  40,  19, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_btnAdd.SetWindowPos	(NULL,  14, 200, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
			m_btnDelete.SetWindowPos(NULL,  71, 200, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
			m_btnUpdate.SetWindowPos(NULL, 255, 200, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
		}
		else
		{
			m_cbCurrent.SetWindowPos	(NULL, 100,  16, 320, 160, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_cbSite.SetWindowPos		(NULL,  75,  48,  90, 160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbBuilding.SetWindowPos	(NULL, 237,  48,  60, 160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbRoom.SetWindowPos		(NULL,  75,  73,  90, 160, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_cbCamera.SetWindowPos		(NULL, 237,  73,  60, 160, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_ID.SetWindowPos		(NULL, 373,  52,  50,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_Pass.SetWindowPos		(NULL, 492,  52,  70,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_IP.SetWindowPos		(NULL, 373,  75, 110,  19, SWP_NOZORDER|SWP_SHOWWINDOW);
			m_Port.SetWindowPos		(NULL, 522,  75,  40,  19, SWP_NOZORDER|SWP_SHOWWINDOW);

			m_btnAdd.SetWindowPos	(NULL, 591,  22, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
			m_btnDelete.SetWindowPos(NULL, 591,  48, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
			m_btnUpdate.SetWindowPos(NULL, 591,  74, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
		}
	}
	else
	{
		m_cbCurrent.ShowWindow(SW_HIDE);
		m_cbSite.ShowWindow(SW_HIDE);
		m_cbBuilding.ShowWindow(SW_HIDE);
		m_cbRoom.ShowWindow(SW_HIDE);
		m_cbCamera.ShowWindow(SW_HIDE);

		m_ID.ShowWindow(SW_HIDE);
		m_Pass.ShowWindow(SW_HIDE);
		m_IP.ShowWindow(SW_HIDE);
		m_Port.ShowWindow(SW_HIDE);

		m_btnAdd.ShowWindow(SW_HIDE);
		m_btnDelete.ShowWindow(SW_HIDE);
		m_btnUpdate.ShowWindow(SW_HIDE);
	}
}

void CMegaDrawerOrganize::SetSites(map<CString, CSite> * pSites)
{
	m_pSites = pSites;

	// clear list
	m_cbCurrent.ResetContent();
	m_cbSite.ResetContent();
	m_cbBuilding.ResetContent();
	m_cbRoom.ResetContent();
	m_cbCamera.ResetContent();
	m_ID.SetWindowText("");
	m_Pass.SetWindowText("");
	m_IP.SetWindowText("");
	m_Port.SetWindowText("");

	// refill list
	map<CString,CSite>::const_iterator s;
	map<CString,CBuilding>::const_iterator b;
	map<CString,CRoom>::const_iterator r;
	map<CString,CInfo>::const_iterator c;

	for(s = m_pSites->begin(); s != m_pSites->end(); s++)
	{
		for(b = (s->second).m_Buildings.begin(); b != (s->second).m_Buildings.end(); b++)
		{
			for(r = (b->second).m_Rooms.begin(); r != (b->second).m_Rooms.end(); r++)
			{
				for(c = (r->second).m_Cameras.begin(); c != (r->second).m_Cameras.end(); c++)
				{
					char name[1024];
					sprintf(name, STRING_PARAM, (LPCSTR) s->first, (LPCSTR) b->first, (LPCSTR) r->first, (LPCSTR) c->first);
					m_cbCurrent.AddString(name);
				}
			}
		}
		// fill sites combobox
		m_cbSite.AddString(s->first);
	}

	m_cbCurrent.RecalcMinWidth();
	m_cbSite.RecalcMinWidth();

	// retrieve last connection params from registry
	char str[1024]={0}, s1[1024]={0}, s2[1024]={0}, s3[1024]={0}, s4[1024]={0};
	REGISTRY_LoadString(KEY_LAST_SITE_CONNECTED, str, 1024);
	sscanf(str, STRING_PARAM, s1, s2, s3, s4);
	sprintf(str, STRING_PARAM, s1, s2, s3, s4);
	if(LB_ERR != m_cbCurrent.SelectString(-1, str))
		OnCurrentCameraChange();
}

void CMegaDrawerOrganize::UpdateMemo()
{
	int idx = m_cbSite.GetCurSel();
	CString strSite("");
	m_cbSite.GetLBText(idx, strSite);

	idx = m_cbBuilding.GetCurSel();
	CString strBuilding("");
	m_cbBuilding.GetLBText(idx, strBuilding);

	idx = m_cbRoom.GetCurSel();
	CString strRoom("");
	m_cbRoom.GetLBText(idx, strRoom);

	idx = m_cbCamera.GetCurSel();
	CString strCamera("");
	m_cbCamera.GetLBText(idx, strCamera);

	char buf[1024];
	sprintf(buf, STRING_PARAM, (LPCSTR) strSite, (LPCSTR) strBuilding, (LPCSTR) strRoom, (LPCSTR) strCamera);
	idx = m_cbCurrent.FindStringExact(-1, buf);
	m_cbCurrent.SetCurSel(idx);

	// send message to parent
	GetParent()->SendMessage(
		WM_CAMERA_SELECTED, 
		(WPARAM) GetDlgCtrlID(), 
		(LPARAM) buf);
}

void CMegaDrawerOrganize::UpdateBuildings(const CSite * pSite)
{
	m_cbBuilding.ResetContent();
	map<CString,CBuilding>::const_iterator b;
	for(b = pSite->m_Buildings.begin(); b != pSite->m_Buildings.end(); b++)
		m_cbBuilding.AddString(b->first);

	m_cbBuilding.RecalcMinWidth();

	m_cbBuilding.SetCurSel(0);
	UpdateRooms(&pSite->m_Buildings.begin()->second);
}

void CMegaDrawerOrganize::UpdateRooms(const CBuilding * pBuilding)
{
	m_cbRoom.ResetContent();
	map<CString,CRoom>::const_iterator r;
	for(r = pBuilding->m_Rooms.begin(); r != pBuilding->m_Rooms.end(); r++)
		m_cbRoom.AddString(r->first);

	m_cbRoom.RecalcMinWidth();

	m_cbRoom.SetCurSel(0);
	UpdateCameras(&pBuilding->m_Rooms.begin()->second);
}

void CMegaDrawerOrganize::UpdateCameras(const CRoom * pRoom)
{
	m_cbCamera.ResetContent();
	map<CString,CInfo>::const_iterator c;
	for(c = pRoom->m_Cameras.begin(); c != pRoom->m_Cameras.end(); c++)
		m_cbCamera.AddString(c->first);

	m_cbCamera.RecalcMinWidth();

	m_cbCamera.SetCurSel(0);
	UpdateInfo(&pRoom->m_Cameras.begin()->second);
}

void CMegaDrawerOrganize::UpdateInfo(const CInfo * pInfo)
{
	char buf[100];
	m_ID.SetWindowText(itoa(pInfo->m_iID, buf, 10));
	m_Pass.SetWindowText(pInfo->m_strPassword);
	m_IP.SetWindowText(pInfo->m_ip);
	m_Port.SetWindowText(itoa(pInfo->m_port, buf, 10));

	UpdateMemo();
}

void CMegaDrawerOrganize::SelectCamera(char * pszCameraSign)
{
	int idx = m_cbCurrent.FindStringExact(-1, pszCameraSign);
	m_cbCurrent.SetCurSel(idx);
	OnCurrentCameraChange();
}


BEGIN_MESSAGE_MAP(CMegaDrawerOrganize, CMegaDrawer)
	//{{AFX_MSG_MAP(CMegaDrawerOrganize)
	ON_CBN_SELENDOK	(IDC_CURRENT,	OnCurrentCameraChange)
	ON_CBN_SELENDOK	(IDC_SITE,		OnSiteChange)
	ON_CBN_SELENDOK	(IDC_BUILDING,	OnBuildingChange)
	ON_CBN_SELENDOK	(IDC_ROOM,		OnRoomChange)
	ON_CBN_SELENDOK	(IDC_CAMERA,	OnCameraChange)

	ON_BN_CLICKED	(IDC_ADD,		OnAddCamera)
	ON_BN_CLICKED	(IDC_DEL,		OnDelCamera)
	ON_BN_CLICKED	(IDC_UPDATE,	OnUpdateCamera)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMegaDrawerOrganize message handlers
void CMegaDrawerOrganize::OnCurrentCameraChange()
{
	int idx = m_cbCurrent.GetCurSel();
	if(idx == CB_ERR)	// addressbook is empty
	{
		m_cbCurrent.SetWindowText("");
		m_cbSite.SetWindowText("");
		m_cbBuilding.SetWindowText("");
		m_cbRoom.SetWindowText("");
		m_cbCamera.SetWindowText("");
		m_ID.SetWindowText("");
		m_IP.SetWindowText("");
		m_Pass.SetWindowText("");
		m_Port.SetWindowText("");
		return ;
	}

	char buf[1024];
	m_cbCurrent.GetLBText(idx, buf);
	char strSite[1024], strBuilding[1024], strRoom[1024], strCamera[1024];
	sscanf(buf, STRING_PARAM, strSite, strBuilding, strRoom, strCamera);

	m_strCurSite		= strSite;
	m_strCurBuilding	= strBuilding;
	m_strCurRoom		= strRoom;
	m_strCurCamera		= strCamera;

	CSite site = m_pSites->find(strSite)->second;
	CBuilding building = site.m_Buildings.find(strBuilding)->second;
	CRoom room = building.m_Rooms.find(strRoom)->second;
	CInfo info = room.m_Cameras.find(strCamera)->second;

	// re-fill & select proper strings in sites, buildings, rooms, cameras comboboxes
	map<CString,CSite>::const_iterator s;
	map<CString,CBuilding>::const_iterator b;
	map<CString,CRoom>::const_iterator r;
	map<CString,CInfo>::const_iterator c;
	// sites
	int nSiteIdx = m_cbSite.FindStringExact(-1, strSite);
	m_cbSite.SetCurSel(nSiteIdx);

	site = m_pSites->find(strSite)->second;
	// buildings
	m_cbBuilding.ResetContent();
	for(b = site.m_Buildings.begin(); b != site.m_Buildings.end(); b++)
		m_cbBuilding.AddString(b->first);

	m_cbBuilding.RecalcMinWidth();

	int nBuildingIdx = m_cbBuilding.FindStringExact(-1, strBuilding);
	m_cbBuilding.SetCurSel(nBuildingIdx);

	building = site.m_Buildings.find(strBuilding)->second;
	// rooms
	m_cbRoom.ResetContent();
	for(r = building.m_Rooms.begin(); r != building.m_Rooms.end(); r++)
		m_cbRoom.AddString(r->first);

	m_cbRoom.RecalcMinWidth();
	int nRoomIdx = m_cbRoom.FindStringExact(-1, strRoom);
	m_cbRoom.SetCurSel(nRoomIdx);

	room = building.m_Rooms.find(strRoom)->second;
	// cameras
	m_cbCamera.ResetContent();
	for(c = room.m_Cameras.begin(); c != room.m_Cameras.end(); c++)
		m_cbCamera.AddString(c->first);

	m_cbCamera.RecalcMinWidth();
	int nCameraIdx = m_cbCamera.FindStringExact(-1, strCamera);
	m_cbCamera.SetCurSel(nCameraIdx);

	char conv_buf[100];
	m_ID.SetWindowText(itoa(info.m_iID, conv_buf, 10));
	m_Pass.SetWindowText(info.m_strPassword);
	m_IP.SetWindowText(info.m_ip);
	m_Port.SetWindowText(itoa(info.m_port, conv_buf, 10));

	// send message to parent
	GetParent()->SendMessage(
		WM_CAMERA_SELECTED, 
		(WPARAM) GetDlgCtrlID(), 
		(LPARAM) buf);
}

void CMegaDrawerOrganize::OnSiteChange()
{
	int idx = m_cbSite.GetCurSel();
	m_cbSite.GetLBText(idx, m_strCurSite);

	CSite site = m_pSites->find(m_strCurSite)->second;
	UpdateBuildings(&m_pSites->find(m_strCurSite)->second);
}

void CMegaDrawerOrganize::OnBuildingChange()
{
	CSite site = m_pSites->find(m_strCurSite)->second;

	int idx = m_cbBuilding.GetCurSel();
	m_cbBuilding.GetLBText(idx, m_strCurBuilding);

	UpdateRooms(&site.m_Buildings.find(m_strCurBuilding)->second);
}

void CMegaDrawerOrganize::OnRoomChange()
{
	CSite site = m_pSites->find(m_strCurSite)->second;
	CBuilding building = site.m_Buildings.find(m_strCurBuilding)->second;

	int idx = m_cbRoom.GetCurSel();
	m_cbRoom.GetLBText(idx, m_strCurRoom);

	UpdateCameras(&building.m_Rooms.find(m_strCurRoom)->second);
}

void CMegaDrawerOrganize::OnCameraChange()
{
	CSite site = m_pSites->find(m_strCurSite)->second;
	CBuilding building = site.m_Buildings.find(m_strCurBuilding)->second;
	CRoom room = building.m_Rooms.find(m_strCurRoom)->second;

	int idx = m_cbCamera.GetCurSel();
	m_cbCamera.GetLBText(idx, m_strCurCamera);

	UpdateInfo(&room.m_Cameras.find(m_strCurCamera)->second);
}

void CMegaDrawerOrganize::OnDelCamera()
{
	// locate current camera
	int idxSite = m_cbSite.FindStringExact(-1, m_strCurSite);
	map<CString,CSite>::iterator s = m_pSites->find(m_strCurSite);

	int idxBuilding = m_cbBuilding.FindStringExact(-1, m_strCurBuilding);
	map<CString,CBuilding>::iterator b = s->second.m_Buildings.find(m_strCurBuilding);

	int idxRoom = m_cbRoom.FindStringExact(-1, m_strCurRoom);
	map<CString,CRoom>::iterator r = b->second.m_Rooms.find(m_strCurRoom);

	int idxCamera = m_cbCamera.FindStringExact(-1, m_strCurCamera);
	map<CString,CInfo>::iterator c = r->second.m_Cameras.find(m_strCurCamera);

	// delete current camera
	r->second.m_Cameras.erase(c);
	m_cbCamera.DeleteString(idxCamera);
	if(r->second.m_Cameras.empty())
	{
		// delete room
		b->second.m_Rooms.erase(r);
		m_cbRoom.DeleteString(idxRoom);
		if(b->second.m_Rooms.empty())
		{
			// delete building
			s->second.m_Buildings.erase(b);
			m_cbBuilding.DeleteString(idxBuilding);
			if(s->second.m_Buildings.empty())
			{
				// delete site
				m_pSites->erase(s);
				m_cbSite.DeleteString(idxSite);
				if(m_pSites->empty())
				{
					MessageBox("Address book is empty");
					m_strCurSite.Empty();
					m_strCurBuilding.Empty();
					m_strCurRoom.Empty();
					m_strCurCamera.Empty();
				}
			}
		}
	}
	m_cbSite.RecalcMinWidth();
	m_cbBuilding.RecalcMinWidth();
	m_cbRoom.RecalcMinWidth();
	m_cbCamera.RecalcMinWidth();

	// remember currently selected camera
	int idx = m_cbCurrent.GetCurSel();

	// notify parent about addressbook change
	GetParent()->SendMessage(WM_ADDRESSBOOK_CHANGED);

	// select previous camera
	if(idx == 0)
	{
		if(m_cbCurrent.SetCurSel(0) == CB_ERR)
			m_cbCurrent.SetCurSel(-1);
	}
	else
	{
		if(m_cbCurrent.SetCurSel(idx-1) == CB_ERR)
			m_cbCurrent.SetCurSel(-1);
	}

	// update other comboboxes
	OnCurrentCameraChange();
}

void CMegaDrawerOrganize::OnUpdateCamera()
{
	// locate current camera
	int DeleteOld=1;
	int idxSite = m_cbSite.FindStringExact(-1, m_strCurSite);
	map<CString,CSite>::iterator s = m_pSites->find(m_strCurSite);

	int idxBuilding = m_cbBuilding.FindStringExact(-1, m_strCurBuilding);
	map<CString,CBuilding>::iterator b = s->second.m_Buildings.find(m_strCurBuilding);

	int idxRoom = m_cbRoom.FindStringExact(-1, m_strCurRoom);
	map<CString,CRoom>::iterator r = b->second.m_Rooms.find(m_strCurRoom);

	int idxCamera = m_cbCamera.FindStringExact(-1, m_strCurCamera);
	map<CString,CInfo>::iterator c = r->second.m_Cameras.find(m_strCurCamera);

	// get new values
	CString strNewSite, strNewBuilding, strNewRoom, strNewCamera;
	m_cbSite.GetWindowText(strNewSite);
	m_cbBuilding.GetWindowText(strNewBuilding);
	m_cbRoom.GetWindowText(strNewRoom);
	m_cbCamera.GetWindowText(strNewCamera);

	CString strID, strIP, strPort, strPass;
	m_ID.GetWindowText(strID);
	m_IP.GetWindowText(strIP);
	m_Port.GetWindowText(strPort);
	m_Pass.GetWindowText(strPass);

	if(strPass.IsEmpty())
	{
	  strPass = "demo";
	  m_Pass.SetWindowText(strPass);
	}

	// change current camera
	// change CInfo
	c->second.m_iID = atoi(strID);
	c->second.setAddress(strIP);
	c->second.m_port = atoi(strPort);
	c->second.setPassword(strPass);

	// 1. insert new camera
	{
		// 1. check for new site
		if(m_strCurSite.Compare(strNewSite))
		{
			(*m_pSites)[strNewSite].m_Buildings[strNewBuilding].m_Rooms[strNewRoom].m_Cameras[strNewCamera] = c->second;
		}
		else
		// 2. check for new building
		if(m_strCurBuilding.Compare(strNewBuilding))
		{
			s->second.m_Buildings[strNewBuilding].m_Rooms[strNewRoom].m_Cameras[strNewCamera] = c->second;
		}
		else
		// 3. check for new room
		if(m_strCurRoom.Compare(strNewRoom))
		{
			b->second.m_Rooms[strNewRoom].m_Cameras[strNewCamera] = c->second;
		}
		else
		// 4. check for new camera
		// if no site, no building, no room added and camera name is same - show warning and do nothing
		if(m_strCurCamera.Compare(strNewCamera))
		{
			r->second.m_Cameras[strNewCamera] = c->second;
		}
		else
		{
			//MessageBox("nothing changed! what you wanted to do?");
			r->second.m_Cameras[strNewCamera] = c->second;
			DeleteOld=0;// do not delete, only IP/ID/Password were changed
			//return ;
		}
	}

	// 2. delete old camera
	if (DeleteOld) {
		r->second.m_Cameras.erase(c);
		m_cbCamera.DeleteString(idxCamera);
		if(r->second.m_Cameras.empty())
		{
			// delete room
			b->second.m_Rooms.erase(r);
			m_cbRoom.DeleteString(idxRoom);
			if(b->second.m_Rooms.empty())
			{
				// delete building
				s->second.m_Buildings.erase(b);
				m_cbBuilding.DeleteString(idxBuilding);
				if(s->second.m_Buildings.empty())
				{
					// delete site
					m_pSites->erase(s);
					m_cbSite.DeleteString(idxSite);
					if(m_pSites->empty())
					{
						MessageBox("Address book is empty");
					}
				}
			}
		}
	}

	// remember updated camera signature
	char buf[1024];
	sprintf(buf, STRING_PARAM, (LPCSTR) strNewSite, (LPCSTR) strNewBuilding, (LPCSTR) strNewRoom, (LPCSTR) strNewCamera);

	// notify parent about addressbook change
	GetParent()->SendMessage(WM_ADDRESSBOOK_CHANGED);

	// set selection at updated cam
	int idx = m_cbCurrent.FindStringExact(-1, buf);
	m_cbCurrent.SetCurSel(idx);

	// update other comboboxes
	OnCurrentCameraChange();
}

void CMegaDrawerOrganize::OnAddCamera()
{
	// get new values
	CString strNewSite, strNewBuilding, strNewRoom, strNewCamera;
	m_cbSite.GetWindowText(strNewSite);
	m_cbBuilding.GetWindowText(strNewBuilding);
	m_cbRoom.GetWindowText(strNewRoom);
	m_cbCamera.GetWindowText(strNewCamera);
	// check basic params
	if(	strNewSite.IsEmpty() || 
		strNewBuilding.IsEmpty() || 
		strNewRoom.IsEmpty() || 
		strNewCamera.IsEmpty()	)
	{
		MessageBox("some of basic parameters are missing");
		return ;
	}

	CString strID, strIP, strPort, strPass;
	m_ID.GetWindowText(strID);
	m_IP.GetWindowText(strIP);
	m_Port.GetWindowText(strPort);
	m_Pass.GetWindowText(strPass);

	if(strPass.IsEmpty())
	{
	  strPass = "demo";
	  m_Pass.SetWindowText(strPass);
	}
    

	// check info params
	if(	strID.IsEmpty() || 
		strIP.IsEmpty() || 
		strPort.IsEmpty() || 
		strPass.IsEmpty()	)
	{
		MessageBox("Some of encoder parameters are missing");
		return ;
	}

	CSite site;
	CBuilding building;
	CRoom room;
	CInfo info;

	info.m_iID = atoi(strID);
	info.setAddress(strIP);
	info.m_port = atoi(strPort);
	info.setPassword(strPass);
	// set default parameters
	/*
	Frame rate of transmission (e.g., 15)
	Quality (e.g. 10, unused in current version)
	Bit rate, (e.g. 200, unused in current version) 
	Vertical resolution (e.g., 320)
	Horizontal resolution (e.g., 240)
	*/
	info.m_iFrameRate = 30;
	info.m_iQualityRange = 10;
	info.m_iBitrate = 500;
	info.m_iWidth = 320;
	info.m_iHeight = 240;

	// add new camera
	// 1. check for new site
	if(m_strCurSite.Compare(strNewSite))
	{
		(*m_pSites)[strNewSite].m_Buildings[strNewBuilding].m_Rooms[strNewRoom].m_Cameras[strNewCamera] = info;
	}
	else
	// 2. check for new building
	if(m_strCurBuilding.Compare(strNewBuilding))
	{
		// locate current camera
		map<CString,CSite>::iterator s = m_pSites->find(m_strCurSite);
		s->second.m_Buildings[strNewBuilding].m_Rooms[strNewRoom].m_Cameras[strNewCamera] = info;
	}
	else
	// 3. check for new room
	if(m_strCurRoom.Compare(strNewRoom))
	{
		// locate current camera
		map<CString,CSite>::iterator s = m_pSites->find(m_strCurSite);
		map<CString,CBuilding>::iterator b = s->second.m_Buildings.find(m_strCurBuilding);
		b->second.m_Rooms[strNewRoom].m_Cameras[strNewCamera] = info;
	}
	else
	// 4. check for new camera
	// if no site, no building, no room added and camera name is same - show warning and do nothing
	if(m_strCurCamera.Compare(strNewCamera))
	{
		// locate current camera
		map<CString,CSite>::iterator s = m_pSites->find(m_strCurSite);
		map<CString,CBuilding>::iterator b = s->second.m_Buildings.find(m_strCurBuilding);
		map<CString,CRoom>::iterator r = b->second.m_Rooms.find(m_strCurRoom);
		r->second.m_Cameras[strNewCamera] = info;
	}
	else
	{
		MessageBox("Please change Location/Organization/Department or User Name\nto add new camera.");
		return ;
	}

	// notify parent about addressbook change
	GetParent()->SendMessage(WM_ADDRESSBOOK_CHANGED);

	// select newly added camera
	char buf[1024];
	sprintf(buf, STRING_PARAM, (LPCSTR) strNewSite, (LPCSTR) strNewBuilding, (LPCSTR) strNewRoom, (LPCSTR) strNewCamera);
	int idx = m_cbCurrent.FindStringExact(-1, buf);
	m_cbCurrent.SetCurSel(idx);

	// update other comboboxes
	OnCurrentCameraChange();
}
